﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using LCTNote.Models;

namespace LCTNote.Services
{
    class Service
    {
        static string connectionString = "Server=123.30.187.4; User ID=rtcmfraf_Moodle; Password=Mo0@g.c";

        /// <summary>
        /// Hàm thực thi lấy về DataReader và gán dòng đầu tiên vào T-Moodle
        /// </summary>
        /// <typeparam name="T">Tên Model</typeparam>
        /// <param name="procedureName">Tên proc thực thi</param>
        /// <param name="parameters">Danh sách tham số (nếu không có thì khai báo: new object[0])</param>
        /// <returns></returns>
        protected static T executeDataReader<T>(string procedureName, object[] parameters)
        {
            SqlConnection connect = new SqlConnection(connectionString);
            try
            {
                connect.Open();

                SqlCommand command = new SqlCommand(procedureName, connect);
                command.CommandType = CommandType.StoredProcedure;
                for (int i = 0; i < parameters.Length; i++)
                {
                    command.Parameters.AddWithValue("@" + i, parameters[i]);
                }
                SqlDataReader dataReader = command.ExecuteReader();

                Model model = (Model)Activator.CreateInstance(typeof(T));
                dataReader.Read();
                model.assignModel(dataReader);
                dataReader.Close();

                connect.Close();

                return (T)Convert.ChangeType(model, typeof(T));
            }
            catch
            {
                connect.Close();
                return default(T);
            }
        }

        /// <summary>
        /// Hàm thực thi lấy về DataReader và gán các dòng vào List T-Model
        /// </summary>
        /// <typeparam name="T">Tên Model</typeparam>
        /// <param name="procedureName">Tên proc thực thi</param>
        /// <param name="parameters">Danh sách tham số (nếu không có thì khai báo: new object[0])</param>
        /// <returns></returns>
        protected static List<T> executeDataReader_List<T>(string procedureName, object[] parameters)
        {
            SqlConnection connect = new SqlConnection(connectionString);
            try
            {
                connect.Open();

                SqlCommand command = new SqlCommand(procedureName, connect);
                command.CommandType = CommandType.StoredProcedure;
                for (int i = 0; i < parameters.Length; i++)
                {
                    command.Parameters.AddWithValue("@" + i, parameters[i]);
                }
                SqlDataReader dataReader = command.ExecuteReader();

                List<Model> model = ((List<T>)Activator.CreateInstance(typeof(List<>).MakeGenericType(typeof(T)))).ConvertAll<Model>(X => (Model)Convert.ChangeType(X, typeof(Model)));
                for (int i = 0; dataReader.Read(); i++)
                {
                    model.Add((Model)Activator.CreateInstance(typeof(T)));
                    model[i].assignModel(dataReader);
                }

                connect.Close();
                return model.ConvertAll<T>(X => (T)Convert.ChangeType(X, typeof(T)));
            }
            catch
            {
                connect.Close();
                return null;
            }
        }

        /// <summary>
        /// Hàm thực thi không có giá trị trả về
        /// </summary>
        /// <param name="procedureName">Tên proc thực thi</param>
        /// <param name="parameters">Danh sách tham số (nếu không có thì khai báo: new object[0])</param>
        /// <returns></returns>
        protected static bool executeNonQuery(string procedureName, object[] parameters)
        {
            SqlConnection connect = new SqlConnection(connectionString);
            try
            {
                connect.Open();

                SqlCommand command = new SqlCommand(procedureName, connect);
                command.CommandType = CommandType.StoredProcedure;
                for (int i = 0; i < parameters.Length; i++)
                {
                    command.Parameters.AddWithValue("@" + i, parameters[i]);
                }
                command.ExecuteNonQuery();
                
                connect.Close();
                return true;
            }
            catch
            {                
                connect.Close();
                return false;
            }
        }

        /// <summary>
        /// Hàm thực thi lấy về giá trị cột đầu tiên của dòng đầu tiên
        /// </summary>
        /// <typeparam name="T">Tên kiểu dữ liệu trả về</typeparam>
        /// <param name="procedureName">Tên proc thực thi</param>
        /// <param name="parameters">Danh sách tham số (nếu không có thì khai báo: new object[0])</param>
        /// <returns></returns>
        protected static T executeScalar<T>(string procedureName, object[] parameters)
        {
            SqlConnection connect = new SqlConnection(connectionString);
            try
            {
                connect.Open();

                SqlCommand command = new SqlCommand(procedureName, connect);
                command.CommandType = CommandType.StoredProcedure;
                for (int i = 0; i < parameters.Length; i++)
                {
                    command.Parameters.AddWithValue("@" + i, parameters[i]);
                }
                object result = command.ExecuteScalar();

                connect.Close();

                return (T)Convert.ChangeType(result, typeof(T));
            }
            catch
            {
                connect.Close();
                return default(T);
            }
        }
    }
}
